<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Map 和 WeakMap 区别以及使用场景 | 技术文档</title>
    <meta name="generator" content="VuePress 1.9.9">
    
    <meta name="description" content="technology-review">
    <meta name="theme-color" content="#3eaf7c">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    
    <link rel="preload" href="/tech-document/assets/css/0.styles.afad9826.css" as="style"><link rel="preload" href="/tech-document/assets/js/app.7336957d.js" as="script"><link rel="preload" href="/tech-document/assets/js/2.4e1184b4.js" as="script"><link rel="preload" href="/tech-document/assets/js/7.d32d6951.js" as="script"><link rel="preload" href="/tech-document/assets/js/12.c2ba2865.js" as="script"><link rel="prefetch" href="/tech-document/assets/js/10.403778a6.js"><link rel="prefetch" href="/tech-document/assets/js/11.1b3238dc.js"><link rel="prefetch" href="/tech-document/assets/js/13.10289b8b.js"><link rel="prefetch" href="/tech-document/assets/js/14.d292f43c.js"><link rel="prefetch" href="/tech-document/assets/js/15.2194d6d3.js"><link rel="prefetch" href="/tech-document/assets/js/16.42e9ba11.js"><link rel="prefetch" href="/tech-document/assets/js/17.a49afd61.js"><link rel="prefetch" href="/tech-document/assets/js/18.98476456.js"><link rel="prefetch" href="/tech-document/assets/js/19.29a251d2.js"><link rel="prefetch" href="/tech-document/assets/js/20.ca55bb01.js"><link rel="prefetch" href="/tech-document/assets/js/21.ae42376a.js"><link rel="prefetch" href="/tech-document/assets/js/22.b1bc092f.js"><link rel="prefetch" href="/tech-document/assets/js/23.38f4ebdf.js"><link rel="prefetch" href="/tech-document/assets/js/24.8c3f712c.js"><link rel="prefetch" href="/tech-document/assets/js/25.317efa81.js"><link rel="prefetch" href="/tech-document/assets/js/26.afeef7fe.js"><link rel="prefetch" href="/tech-document/assets/js/27.44fccbaf.js"><link rel="prefetch" href="/tech-document/assets/js/28.290da4aa.js"><link rel="prefetch" href="/tech-document/assets/js/29.fa50ae0a.js"><link rel="prefetch" href="/tech-document/assets/js/3.414f2d7e.js"><link rel="prefetch" href="/tech-document/assets/js/30.88d887a4.js"><link rel="prefetch" href="/tech-document/assets/js/31.567937c9.js"><link rel="prefetch" href="/tech-document/assets/js/32.27fa7a1a.js"><link rel="prefetch" href="/tech-document/assets/js/33.4eb80605.js"><link rel="prefetch" href="/tech-document/assets/js/34.cf229122.js"><link rel="prefetch" href="/tech-document/assets/js/35.945a7237.js"><link rel="prefetch" href="/tech-document/assets/js/36.d0a4767e.js"><link rel="prefetch" href="/tech-document/assets/js/37.4c6954a0.js"><link rel="prefetch" href="/tech-document/assets/js/38.2bccf61b.js"><link rel="prefetch" href="/tech-document/assets/js/39.2040339f.js"><link rel="prefetch" href="/tech-document/assets/js/4.254b04cb.js"><link rel="prefetch" href="/tech-document/assets/js/40.cc2c8a0d.js"><link rel="prefetch" href="/tech-document/assets/js/41.61cf17ce.js"><link rel="prefetch" href="/tech-document/assets/js/42.b38eb7ca.js"><link rel="prefetch" href="/tech-document/assets/js/43.4ea8ba50.js"><link rel="prefetch" href="/tech-document/assets/js/5.44a12058.js"><link rel="prefetch" href="/tech-document/assets/js/6.237b9cc2.js"><link rel="prefetch" href="/tech-document/assets/js/8.4049e9dd.js"><link rel="prefetch" href="/tech-document/assets/js/9.bec82895.js">
    <link rel="stylesheet" href="/tech-document/assets/css/0.styles.afad9826.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/tech-document/" class="home-link router-link-active"><!----> <span class="site-name">技术文档</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/tech-document/" class="nav-link">
  首页
</a></div><div class="nav-item"><a href="/tech-document/archive/" class="nav-link">
  文章归档
</a></div><div class="nav-item"><a href="/tech-document/css/" class="nav-link">
  HTML/CSS
</a></div><div class="nav-item"><a href="/tech-document/javascript/" class="nav-link router-link-active">
  Javascript
</a></div><div class="nav-item"><a href="/tech-document/react/" class="nav-link">
  React
</a></div><div class="nav-item"><a href="/tech-document/vue/" class="nav-link">
  Vue
</a></div><div class="nav-item"><a href="/tech-document/typescript/" class="nav-link">
  Typescript
</a></div><div class="nav-item"><a href="/tech-document/webpack/" class="nav-link">
  Webpack
</a></div><div class="nav-item"><a href="/tech-document/algorithm/" class="nav-link">
  算法
</a></div><div class="nav-item"><a href="/tech-document/network/" class="nav-link">
  网络知识
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="个人博客" class="dropdown-title"><span class="title">个人博客</span> <span class="arrow down"></span></button> <button type="button" aria-label="个人博客" class="mobile-dropdown-title"><span class="title">个人博客</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://blog.csdn.net/qq_39583550" target="_blank" rel="noopener noreferrer" class="nav-link external">
  CSDN
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://cjperfect.gitee.io/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  个人工具
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/tech-document/" class="nav-link">
  首页
</a></div><div class="nav-item"><a href="/tech-document/archive/" class="nav-link">
  文章归档
</a></div><div class="nav-item"><a href="/tech-document/css/" class="nav-link">
  HTML/CSS
</a></div><div class="nav-item"><a href="/tech-document/javascript/" class="nav-link router-link-active">
  Javascript
</a></div><div class="nav-item"><a href="/tech-document/react/" class="nav-link">
  React
</a></div><div class="nav-item"><a href="/tech-document/vue/" class="nav-link">
  Vue
</a></div><div class="nav-item"><a href="/tech-document/typescript/" class="nav-link">
  Typescript
</a></div><div class="nav-item"><a href="/tech-document/webpack/" class="nav-link">
  Webpack
</a></div><div class="nav-item"><a href="/tech-document/algorithm/" class="nav-link">
  算法
</a></div><div class="nav-item"><a href="/tech-document/network/" class="nav-link">
  网络知识
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="个人博客" class="dropdown-title"><span class="title">个人博客</span> <span class="arrow down"></span></button> <button type="button" aria-label="个人博客" class="mobile-dropdown-title"><span class="title">个人博客</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://blog.csdn.net/qq_39583550" target="_blank" rel="noopener noreferrer" class="nav-link external">
  CSDN
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://cjperfect.gitee.io/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  个人工具
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>JavaScript</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/tech-document/javascript/" aria-current="page" class="sidebar-link">浏览器渲染</a></li><li><a href="/tech-document/javascript/Ajax、axios、fetch的区别.html" class="sidebar-link">Ajax、axios、fetch的区别</a></li><li><a href="/tech-document/javascript/axios的知识点.html" class="sidebar-link">axios的知识点</a></li><li><a href="/tech-document/javascript/JS代码实现题.html" class="sidebar-link">JS代码实现题</a></li><li><a href="/tech-document/javascript/JS小知识点.html" class="sidebar-link">JS小知识点</a></li><li><a href="/tech-document/javascript/Map和WeakMap区别以及使用场景.html" class="active sidebar-link">Map 和 WeakMap 区别以及使用场景</a></li><li><a href="/tech-document/javascript/Polyfill是什么.html" class="sidebar-link">Polyfill是什么</a></li><li><a href="/tech-document/javascript/requestIdleCallback和requestAnimationFrame详解 .html" class="sidebar-link">requestIdleCallback和requestAnimationFrame详解</a></li><li><a href="/tech-document/javascript/setInterval 不准确的问题.html" class="sidebar-link">setInterval 不准确的问题</a></li><li><a href="/tech-document/javascript/图片懒加载.html" class="sidebar-link">原生JS实现图片懒加载</a></li><li><a href="/tech-document/javascript/引起内存泄漏的操作有哪些.html" class="sidebar-link">引起内存泄漏的操作有哪些</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><div class="custom-header" data-v-46893521><h1 class="title" data-v-46893521></h1> <div class="name" data-v-46893521>
    作者:
    <span data-v-46893521></span></div> <div class="categories" data-v-46893521>
    分类:
    </div> <div class="tags" data-v-46893521>
    标签:
    </div> <div class="date" data-v-46893521>
    创建时间:
    <span data-v-46893521></span></div></div> <h2 id="map-结构"><a href="#map-结构" class="header-anchor">#</a> Map 结构</h2> <p><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map" target="_blank" rel="noopener noreferrer">MDN 介绍<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>Map` 类似于对象，但是键名不限于 String 和 Symbol 两种类型，它的 key 可以是任意类型，结构优于传统的对象。</p> <p>如下：map 使用 Object 作为 key</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> key <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><img src="/tech-document/assets/img/1674957119849.8fbbad2b.png" alt="1674957119849"></p> <details class="custom-block details"><summary>Map 和 Object 的比较</summary> <table><thead><tr><th style="text-align:left;"></th> <th style="text-align:left;">Map</th> <th style="text-align:left;">Object</th></tr></thead> <tbody><tr><td style="text-align:left;">意外的键</td> <td style="text-align:left;"><code>Map</code> 默认情况不包含任何键。只包含显式插入的键。</td> <td style="text-align:left;">一个 <code>Object</code> 有一个原型，原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。</td></tr> <tr><td style="text-align:left;">键的类型</td> <td style="text-align:left;">一个 <code>Map</code> 的键可以是<strong>任意值</strong>，包括函数、对象或任意基本类型。</td> <td style="text-align:left;">一个 <code>Object</code> 的键必须是一个 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String" target="_blank" rel="noopener noreferrer"><code>String</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 或是 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol" target="_blank" rel="noopener noreferrer"><code>Symbol</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。</td></tr> <tr><td style="text-align:left;">键的顺序</td> <td style="text-align:left;"><code>Map</code> 中的键是有序的。因此，当迭代的时候，一个 <code>Map</code> 对象以插入的顺序返回键值。</td> <td style="text-align:left;">虽然 <code>Object</code> 的键目前是有序的，但并不总是这样，而且这个顺序是复杂的。因此，最好不要依赖属性的顺序。</td></tr> <tr><td style="text-align:left;">Size</td> <td style="text-align:left;"><code>Map</code> 的键值对个数可以轻易地通过 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/size" target="_blank" rel="noopener noreferrer"><code>size</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 属性获取。</td> <td style="text-align:left;"><code>Object</code> 的键值对个数只能手动计算。</td></tr> <tr><td style="text-align:left;">迭代</td> <td style="text-align:left;"><code>Map</code> 是 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols" target="_blank" rel="noopener noreferrer">可迭代的<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 的，所以可以直接被迭代。</td> <td style="text-align:left;"><code>Object</code> 没有实现 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol" target="_blank" rel="noopener noreferrer">迭代协议<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，所以使用 JavaSctipt 的 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of" target="_blank" rel="noopener noreferrer">for...of<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 表达式并不能直接迭代对象。**备注：**对象可以实现迭代协议，或者你可以使用 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys" target="_blank" rel="noopener noreferrer"><code>Object.keys</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 或 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/entries" target="_blank" rel="noopener noreferrer"><code>Object.entries</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...in" target="_blank" rel="noopener noreferrer">for...in<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 表达式允许你迭代一个对象的<em>可枚举</em>属性。</td></tr> <tr><td style="text-align:left;">性能</td> <td style="text-align:left;">在频繁增删键值对的场景下表现更好。</td> <td style="text-align:left;">在频繁添加和删除键值对的场景下未作出优化。</td></tr> <tr><td style="text-align:left;">序列化和解析</td> <td style="text-align:left;">没有元素的序列化和解析的支持。（但是你可以使用携带 <em>replacer</em> 参数的 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify" target="_blank" rel="noopener noreferrer"><code>JSON.stringify()</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 创建一个自己的对 <code>Map</code> 的序列化和解析支持。参见 Stack Overflow 上的提问：<a href="https://stackoverflow.com/q/29085197/" target="_blank" rel="noopener noreferrer">How do you JSON.stringify an ES6 Map?<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>）</td> <td style="text-align:left;">原生的由 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object" target="_blank" rel="noopener noreferrer"><code>Object</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 到 JSON 的序列化支持，使用 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify" target="_blank" rel="noopener noreferrer"><code>JSON.stringify()</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。原生的由 JSON 到 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object" target="_blank" rel="noopener noreferrer"><code>Object</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 的解析支持，使用 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse" target="_blank" rel="noopener noreferrer"><code>JSON.parse()</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。</td></tr></tbody></table></details> <h3 id="map-的特点"><a href="#map-的特点" class="header-anchor">#</a> Map 的特点</h3> <ol><li><p>Map 默认情况下不包含任何键，所有键都是自己添加进去的。不同于 Object 原型链上有一些默认的键。</p></li> <li><p>Map 的键可以是<strong>任意类型</strong>数据，就连函数都可以。</p></li> <li><p>Map 的键值对个数可以<strong>轻易</strong>通过<code>size</code>属性获取，Object 需要手动计算。</p></li> <li><p>Map 在频繁增删键值对的场景下<strong>性能</strong>要比 Object 好。</p></li></ol> <h3 id="什么时候用-map"><a href="#什么时候用-map" class="header-anchor">#</a> 什么时候用 Map</h3> <ol><li>要添加的键值名和 Object 上的默认键值名冲突，又不想改名时，<strong>用 Map</strong></li> <li>需要 String 和 Symbol 以外的数据类型做键值时，<strong>用 Map</strong></li> <li>键值对很多，有需要计算数量时，<strong>用 Map</strong></li> <li>需要频繁增删键值对时，<strong>用 Map</strong></li></ol> <h2 id="什么是-weakmap"><a href="#什么是-weakmap" class="header-anchor">#</a> 什么是 WeakMap</h2> <p><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap" target="_blank" rel="noopener noreferrer">MDN 介绍<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p><code>WeakMap</code>是 ES6 中新增的一种集合类型，叫做“弱映射”。它和<code>Map</code>是兄弟关系，与<code>Map</code>的区别就在于这个<strong>弱字</strong>，API 还是<code>Map</code>的那套（只有<code>set</code> <code>get</code> <code>has</code> <code>delete</code>)</p> <h3 id="weakmap-的特点"><a href="#weakmap-的特点" class="header-anchor">#</a> WeakMap 的特点</h3> <p>只接受对象作为键名（<code>null</code> 除外），不接受其他类型的值作为键名；</p> <h3 id="weakmap-的键名引用的对象是弱引用"><a href="#weakmap-的键名引用的对象是弱引用" class="header-anchor">#</a> WeakMap 的键名引用的对象是弱引用</h3> <p>这是<code>WeakMap</code>结构的关键所在</p> <h4 id="什么是强引用"><a href="#什么是强引用" class="header-anchor">#</a> 什么是强引用</h4> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">d</span><span class="token operator">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">[</span>obj1<span class="token punctuation">,</span> <span class="token string">&quot;这是obj1对象&quot;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">[</span>obj2<span class="token punctuation">,</span> <span class="token string">&quot;这是obj2对象&quot;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>obj1 和 obj2 是两个对象，通过 arr 数组对这两个对象添加一些文字说明，这样就形成了 arr 对 obj1 和 obj2 的应用，这种应用就是<code>强引用</code>，当我们不需要这个对象时候，还需要手动的删除这个引用，解除 arr 对这两个对象的引用，否则垃圾回收机制不会释放这两个对象占用的内存。</p> <div class="language-js extra-class"><pre class="language-js"><code>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="什么是弱引用"><a href="#什么是弱引用" class="header-anchor">#</a> 什么是弱引用</h4> <p>创建一个弱引用对象</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h4 id="图解强引用和弱引用"><a href="#图解强引用和弱引用" class="header-anchor">#</a> 图解强引用和弱引用</h4> <p>强引用：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token string">&quot;引用了obj1对象&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><img src="/tech-document/assets/img/1674959056101.fa1e0349.png" alt="1674959056101"></p> <p>从上图可以看出，obj1 这个对象被引用了两次，因此引用计数为 2。</p> <p>弱引用：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token string">&quot;引用了obj1对象&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><img src="/tech-document/assets/img/1674959263825.8f240cd8.png" alt="1674959263825"></p> <p>从上图可以看出，obj1 被引用了 1 次，引用计数为 1.</p> <div class="custom-block tip"><p class="custom-block-title">提示</p> <p>如果强引用数据被删除时候，我们需要手动的解除引用，而弱引用可以直接等待垃圾回收机制自动清除。</p> <p>当<code>obj1 = null</code>时会解除 obj1 对原数据的引用；</p> <p>weakMap 实例对象对 obj1 所引用的对象是<code>弱引用关系</code>，该数据的引用计数就是 0，因此会被垃圾回收机制清除；</p> <p>map 实例对象是对 obj1 所引用的对象是<code>强引用关系</code>，该数据的引用计数是 1， 因此不会被垃圾回收机制清除。</p></div> <h3 id="weakmap-的应用场景"><a href="#weakmap-的应用场景" class="header-anchor">#</a> WeakMap 的应用场景</h3> <h4 id="_1-dom-节点元数据"><a href="#_1-dom-节点元数据" class="header-anchor">#</a> 1. DOM 节点元数据</h4> <p>因为 weakMap 不会影响垃圾回收，所以可以用来关联元数据</p> <p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/733e38dd1b114563a43e04e8f51a9068~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp" alt="image-20210725171056590"></p> <p>当上面代码执行后，登录按钮从 DOM 树中被删除了，但由于 Map 对节点对象是强引用关系，仍然保存着对按钮的引用，所以会引起内存泄漏</p> <p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4f50f0747e5743cdbecb63d83ea47aed~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp" alt="image-20210725171352098"></p> <p>因此可以采用<code>WeakMap</code>当节点删除后，引用计数为 0，等待垃圾回收机制回收</p> <h4 id="_2-部署私有属性"><a href="#_2-部署私有属性" class="header-anchor">#</a> 2. 部署私有属性</h4> <p>利用弱映射，将内部属性设置为实例的弱引用对象，当实例删除时，私有属性也会随之消失，因此不会内存泄漏</p> <p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9843042808ba4d888d838f9a434e35ed~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp" alt="image-20210725172559971"></p> <h4 id="_3-数据缓存"><a href="#_3-数据缓存" class="header-anchor">#</a> 3. 数据缓存</h4> <p>当我们需要在不修改原有对象的情况下储存某些属性等，而又不想管理这些数据时，可以使用<code>WeakMap</code></p> <p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b77c6e9beef643bd840b59ae4626db5e~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp" alt="image-20210725173257029"></p> <h2 id="map-和-weakmap-的区别"><a href="#map-和-weakmap-的区别" class="header-anchor">#</a> Map 和 WeakMap 的区别</h2> <ol><li><code>Map</code> 的键可以是任意类型，<code>WeakMap</code> 只接受对象作为键（null 除外），不接受其他类型的值作为键</li> <li><code>Map</code> 的键实际上是跟内存地址绑定的，只要内存地址不一样，就视为两个键； <code>WeakMap</code> 的键是弱引用，键所指向的对象可以被垃圾回收，此时键是无效的</li> <li><code>Map</code>可以被遍历， <code>WeakMap</code> 不能被遍历</li></ol> <hr> <ul><li>原文地址：https://juejin.cn/post/6993101968545677319</li></ul></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/tech-document/javascript/JS小知识点.html" class="prev">
        JS小知识点
      </a></span> <span class="next"><a href="/tech-document/javascript/Polyfill是什么.html">
        Polyfill是什么
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----><!----></div></div>
    <script src="/tech-document/assets/js/app.7336957d.js" defer></script><script src="/tech-document/assets/js/2.4e1184b4.js" defer></script><script src="/tech-document/assets/js/7.d32d6951.js" defer></script><script src="/tech-document/assets/js/12.c2ba2865.js" defer></script>
  </body>
</html>
